package com.bbx.taxi.client.widget.Drag;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.bbx.taxi.official.R;
import com.bbx.taxi.client.Adapter.PayDetailsAdapter;
import com.bbx.taxi.client.Bean.Value;
import com.bbx.taxi.client.Util.FormatUtil;

import android.content.Context;
import android.graphics.Typeface;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * Created by Flavien Laurent (flavienlaurent.com) on 23/08/13.
 */
public class DragLayout extends ViewGroup {
	/**
	 * 该拖动试图的开关状态
	 * 
	 */
	public interface OnDragViewStatusListener {
		/** 该拖动试图的开关状态 */
		public void onDragViewStatus(boolean isOpen);
	};

	public OnDragViewStatusListener mOnDragViewStatusListener;

	public void setOnDragViewStatusListener(OnDragViewStatusListener l) {
		mOnDragViewStatusListener = l;
	};

	private final ViewDragHelper mDragHelper;
	private View mDescView;
	private TextView tv_time;
//	private TextView tv_order_type;
	private TextView tv_start;
	private TextView tv_end;
	private TextView tv_pay;
	private TextView tv_wf;
//	private TextView tv_count;
//	private ImageButton ib_kftel;
	private ImageView iv_own;
	/**hint支付类型*/
	private RelativeLayout layout_hint_paytype;
	private TextView tv_hint_paytype;
	private TextView tv_need_pay;
	/**支付的费用明细列表*/
	private ListView listview_paydetail;

	private PayDetailsAdapter mPayDetailsAdapter;
	/**支付费用明细列表*/
	private List<Map<String, String>> list_paydetail=new ArrayList<Map<String,String>>();

	private float mInitialMotionX;
	private float mInitialMotionY;
	/** 可拖动范围（总范围） */
	private int mDragRange;
	private int mTop;
	/** 拖动偏移=拖动的量/可拖动的范围（总范围） 大于0.5f则代表为超过一半 */
	private float mDragOffset;
	private Context context;
	private int onLayoutCount=0;

	public DragLayout(Context context) {
		this(context, null);
		this.context=context;
	}

	public DragLayout(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
		this.context=context;
	}

	public DragLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.context=context;
		mDragHelper = ViewDragHelper.create(this, 1f, new DragHelperCallback());
	}

	@Override
	protected void onFinishInflate() {
		mDescView = findViewById(R.id.desc);
		tv_time = (TextView) mDescView.findViewById(R.id.tv_time);
		tv_wf= (TextView) mDescView.findViewById(R.id.tv_wf);
//		tv_order_type = (TextView) mDescView.findViewById(R.id.tv_order_type);
		tv_start = (TextView) mDescView.findViewById(R.id.tv_start);
		tv_end = (TextView) mDescView.findViewById(R.id.tv_end);
		tv_pay = (TextView) mDescView.findViewById(R.id.tv_pay);
//		tv_count = (TextView) mDescView.findViewById(R.id.tv_count);
//		ib_kftel = (ImageButton) mDescView.findViewById(R.id.ib_kftel);
		tv_need_pay = (TextView) mDescView.findViewById(R.id.tv_need_pay);
//		ib_kftel.setVisibility(View.GONE);
		layout_hint_paytype=(RelativeLayout)mDescView.findViewById(R.id.layout_hint_paytype);
		tv_hint_paytype=(TextView)mDescView.findViewById(R.id.tv_hint_paytype);
		iv_own=(ImageView)mDescView.findViewById(R.id.iv_own);
		listview_paydetail=(ListView) findViewById(R.id.lv_paydetail);
		mPayDetailsAdapter=new PayDetailsAdapter(context, list_paydetail);
		listview_paydetail.setAdapter(mPayDetailsAdapter);
		tv_pay.setTypeface(Typeface.createFromAsset(context.getAssets(),"fonts/num.ttf"));
	}

	/**
	 * 显示最大化，及View滑到原始位置
	 */
	public void maximize() {
		smoothSlideTo(0f);
	}

	/**
	 * 显示最小化，及View滑出屏幕
	 */
	public void minimize() {
		smoothSlideTo(1f);
	}

	/**
	 * 设置时间
	 */
	public void setTime(String text) {
		tv_time.setText(text);
	}

	/**
	 * 设置订单类型
	 */
	public void setOrderType(String text) {
//		tv_order_type.setText(text);
	}

	/**
	 * 设置人数
	 */
	public void setCount(String text) {
//		tv_count.setText(text);
	}

	public void setCountVisibility(int isVisibility) {
//		tv_count.setVisibility(isVisibility);
	}
	/**
	 * 设置往返
	 */
	public void setRound_trip(String text) {
		tv_wf.setText(text);
	}

	/**
	 * 设置出发地
	 */
	public void setStart(String text) {
		tv_start.setText(text);
	}

	/**
	 * 设置目的地
	 */
	public void setEnd(String text) {
		tv_end.setText(text);
	}

	/**
	 * 设置支付多少钱
	 */
	public void setPay(double pay, boolean isPay,String paytype) {
		if (isPay) {
			tv_need_pay.setText(paytype);
//			layout_hint_paytype.setVisibility(View.VISIBLE);
			tv_hint_paytype.setText(paytype);
		}else{
			tv_need_pay.setText(R.string.need_pay);
//			layout_hint_paytype.setVisibility(View.GONE);
		}
		tv_pay.setText(FormatUtil.onFormatDecimal(pay));
	}
    /**
     * 设置费用明细列表
     */
    public void setPayDetailList(List<Map<String, String>> list_paydetail){
    	this.list_paydetail.clear();
    	this.list_paydetail.addAll(list_paydetail);
    	mPayDetailsAdapter.notifyDataSetChanged();
    }
    public void setOwn(String owntype){
    	//判断自费类型
    	try{
    	if(Integer.parseInt(owntype)==Value.NOOWN){
    	iv_own.setImageDrawable(context.getResources().getDrawable(R.drawable.icon_g));
    	}else{
    	iv_own.setImageDrawable(context.getResources().getDrawable(R.drawable.icon_z));
    	}
       }catch(Exception e){}
    }

	/**
	 * 滑动试图，1f则为滑出屏幕，0f则滑到原始位置，目前为横向滑
	 */
	boolean smoothSlideTo(float slideOffset) {
		final int leftBound = getPaddingLeft();
		int x = (int) (leftBound + slideOffset * mDragRange);

		if (mDragHelper.smoothSlideViewTo(mDescView, x, mDescView.getTop())) {
			ViewCompat.postInvalidateOnAnimation(this);
			return true;
		}
		return false;
	}

	private class DragHelperCallback extends ViewDragHelper.Callback {

		/**
		 * 确定当前子view是否可拖动，
		 */
		@Override
		public boolean tryCaptureView(View child, int pointerId) {
			return child == mDescView;
		}

		/**
		 * 该方法在子view位置发生改变时都会被调用，可以在这个方法中做一些拖动过程中渐变的动画等操作,left距离左边的偏移量
		 */
		@Override
		public void onViewPositionChanged(View changedView, int left, int top,
				int dx, int dy) {
			mDragOffset = (float) left / mDragRange;
			mDescView.setPivotX(mDescView.getWidth());

			mDescView.setAlpha(1 - mDragOffset);

			invalidate();
			if (mDragOffset >= 1) {
				if (mOnDragViewStatusListener != null)
					mOnDragViewStatusListener.onDragViewStatus(false);
			} else if (mDragOffset <= 0) {
				if (mOnDragViewStatusListener != null)
					mOnDragViewStatusListener.onDragViewStatus(true);
			}
		}

		/**
		 * 该方法在手势拖动释放的时候被调用，可以在这里设置子View预期到达的位置，
		 * 如果人为的手势拖动没有到达预期位置，我们可以让子View在人为的拖动结束后，再自动关的滑动到指定位置
		 * 
		 * @xvel为X轴的拖动速度正的为向右，0代表滑动停止后一段时间后，释放手指
		 * @yvel为Y轴拖动速度正的为向下
		 */
		@Override
		public void onViewReleased(View releasedChild, float xvel, float yvel) {
			int left = getPaddingLeft();
			// 如果方向向右，或者停止滑动却拖动便宜大于可滑动的一半，则滑动总范围，及整个View滑出屏幕
			// 如果这句话没执行，则代表滑到原始位置。
			if (xvel > 0 || (xvel == 0 && mDragOffset > 0.5f)) {
				left += mDragRange;
			}
			mDragHelper.settleCapturedViewAt(left, 0);
			invalidate();
		}

		/**
		 * 从字面意思就可以看出这是一个获取边界的方法
		 */
		@Override
		public int getViewVerticalDragRange(View child) {
			return mDragRange;
		}

		// @Override
		// public int clampViewPositionVertical(View child, int top, int dy) {
		// final int topBound = getPaddingTop();
		// final int bottomBound = getHeight() - mHeaderView.getHeight() -
		// mHeaderView.getPaddingBottom();
		//
		// final int newTop = Math.min(Math.max(top, topBound), bottomBound);
		// return newTop;
		// }
		/**
		 * 此方法是用来控制水平方向移动的范围，每次调用
		 * 拿到当前的left值跟DragLayout的根布局的paddingleft值做比较，取两者中大的值
		 * ，这样做是为了防止子view左边滑出根布局的左边界。 拿left和padding
		 * left中的较大值跟可滑动范围的右边界（根布局宽度减去子view的宽度）作比较，取较小值，这样做是为了防止子view右边滑出根布局右边界。
		 */
		@Override
		public int clampViewPositionHorizontal(View child, int left, int dx) {
			final int leftBound = getPaddingLeft();
			final int rightBound = getWidth() - 0;

			final int newLeft = Math.min(Math.max(left, leftBound), rightBound);

			return newLeft;
		}
	}

	@Override
	public void computeScroll() {
		if (mDragHelper.continueSettling(true)) {
			ViewCompat.postInvalidateOnAnimation(this);
		}
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		final int action = MotionEventCompat.getActionMasked(ev);

		if ((action != MotionEvent.ACTION_DOWN)) {
			mDragHelper.cancel();
			return super.onInterceptTouchEvent(ev);
		}

		if (action == MotionEvent.ACTION_CANCEL
				|| action == MotionEvent.ACTION_UP) {
			mDragHelper.cancel();
			return false;
		}

		final float x = ev.getX();
		final float y = ev.getY();
		boolean interceptTap = false;
		switch (action) {
		case MotionEvent.ACTION_DOWN: {
			mInitialMotionX = x;
			mInitialMotionY = y;
			interceptTap = mDragHelper.isViewUnder(mDescView, (int) x, (int) y);
			break;
		}

		case MotionEvent.ACTION_MOVE: {
			final float adx = Math.abs(x - mInitialMotionX);
			final float ady = Math.abs(y - mInitialMotionY);
			final int slop = mDragHelper.getTouchSlop();
			/* useless */
			if (ady > slop && adx > ady) {
				mDragHelper.cancel();
				return false;
			}
		}
		}

		return mDragHelper.shouldInterceptTouchEvent(ev) || interceptTap;
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		mDragHelper.processTouchEvent(ev);

		final int action = ev.getAction();
		final float x = ev.getX();
		final float y = ev.getY();
		boolean isDescViewUnder = mDragHelper.isViewUnder(mDescView, (int) x,
				(int) y);
		switch (action & MotionEventCompat.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN: {
			mInitialMotionX = x;
			mInitialMotionY = y;
			break;
		}

		case MotionEvent.ACTION_UP: {
			final float dx = x - mInitialMotionX;
			final float dy = y - mInitialMotionY;
			final int slop = mDragHelper.getTouchSlop();
			if (dx * dx + dy * dy < slop * slop && isDescViewUnder) {
				// if (mDragOffset == 0) {
				// smoothSlideTo(1f);
				// } else {
				// smoothSlideTo(0f);
				// }
			}
			break;
		}
		}

		return isViewHit(mDescView, (int) x, (int) y);
	}

	private boolean isViewHit(View view, int x, int y) {
		int[] viewLocation = new int[2];
		view.getLocationOnScreen(viewLocation);
		int[] parentLocation = new int[2];
		this.getLocationOnScreen(parentLocation);
		int screenX = parentLocation[0] + x;
		int screenY = parentLocation[1] + y;
		return screenX >= viewLocation[0]
				&& screenX < viewLocation[0] + view.getWidth()
				&& screenY >= viewLocation[1]
				&& screenY < viewLocation[1] + view.getHeight();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		measureChildren(widthMeasureSpec, heightMeasureSpec);

		int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
		int maxHeight = MeasureSpec.getSize(heightMeasureSpec);

		setMeasuredDimension(
				resolveSizeAndState(maxWidth, widthMeasureSpec, 0),
				resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		if(true){//防止一些手机会多次调用，
		   onLayoutCount++;
		// 初始化可拖动范围===整个布局的宽度=整个屏幕宽度
		mDragRange = getWidth();
		// 默认左上角位置
		// mDescView
		// .layout(0, mTop, r, mTop + b);
		// 默认右上角位置，及屏幕外面
		mDescView.layout(r, mTop, r + mDescView.getMeasuredWidth(), mTop + b);
		}
	}
}
